#include <msg_pack_transfer.h>
#include <csmsg_protocol/bitmap_msg.h>


using namespace std;
using namespace ezycli;

CMsgPara* my_create_para(short msgid, short msgtype)
{
    switch(msgtype)
    {
    case Request:
        {
            switch(msgid)
            {
            case ID_FETCH_BITMAP: return new CReqFetchBitmap;
            case ID_UPDATE_BITMAP: return new CReqUpdateBitmap;
            default: return NULL;
            }
        }

    case Response:
        {
            switch(msgid)
            {
            case ID_FETCH_BITMAP: return new CRspFetchBitmap;
            case ID_UPDATE_BITMAP: return new CRspUpdateBitmap;
            default: return NULL;
            }
        }

    default:
        {
            return NULL;
        }
    }
}

int update_bitmap(unsigned int uin, csmsg_transfer &transfer)
{
    CCSHead cshead;
    cshead.m_nTotalLength = 0;
    cshead.m_nDialogID = -1;
    cshead.m_byOptLength = 0;
    cshead.m_iUin = uin;

    CMsg reqmsg;
    reqmsg.m_stHead.m_shMsgID = ID_UPDATE_BITMAP;
    reqmsg.m_stHead.m_shMsgType = Request;
    reqmsg.m_stHead.m_iMsgSeq = 0;
    reqmsg.m_stHead.m_bSrcFE = 0;
    reqmsg.m_stHead.m_bDstFE = 0;
    reqmsg.m_stHead.m_shSrcID = 0;
    reqmsg.m_stHead.m_shDstID = 0;

    CReqUpdateBitmap *reqparam = new CReqUpdateBitmap;
    reqparam->m_uiSrcUin = uin;
    reqparam->m_stPmt.m_uiUin = uin;
    reqparam->m_stPmt.m_uiOp = eop_set_byte;
    reqparam->m_stPmt.m_ucVal = 0xff;
    reqparam->m_stPmt.m_ushOffset = 1;
    reqparam->m_stPmt.m_stCAS.m_ucCASType = ect_chk_none;
    reqparam->m_stPmt.m_stCAS.m_uiRev = 4;

    reqmsg.m_pMsgPara = reqparam;

    int ret = transfer.send_csmsg(cshead, reqmsg);

    if (ret)
    {
        printf("send failed ret:%d, err:%s\n", ret, transfer.get_errmsg());
        return -1;
    }

    CMsg rspmsg;
    ret = transfer.recv_csmsg(&cshead, &rspmsg);
    if (ret)
    {
        printf("recv failed ret:%d, err:%s\n", ret, transfer.get_errmsg());
        return -1;
    }

    CRspUpdateBitmap *rspparam = (CRspUpdateBitmap*)rspmsg.m_pMsgPara;
    printf("update result:%d, rev:%ld\n", rspparam->m_iResult, rspparam->m_uiRev);

    return 0;
}

int fetch_bitmap(unsigned int uin, csmsg_transfer &transfer)
{
    CCSHead cshead;
    cshead.m_nTotalLength = 0;
    cshead.m_nDialogID = -1;
    cshead.m_byOptLength = 0;
    cshead.m_iUin = uin;

    CMsg reqmsg;
    reqmsg.m_stHead.m_shMsgID = ID_FETCH_BITMAP;
    reqmsg.m_stHead.m_shMsgType = Request;
    reqmsg.m_stHead.m_iMsgSeq = 0;
    reqmsg.m_stHead.m_bSrcFE = 0;
    reqmsg.m_stHead.m_bDstFE = 0;
    reqmsg.m_stHead.m_shSrcID = 0;
    reqmsg.m_stHead.m_shDstID = 0;

    CReqFetchBitmap *reqparam = new CReqFetchBitmap;
    reqparam->m_uiSrcUin = 0;
    reqparam->m_uiFlag = 0;
    reqparam->m_uiUin = uin;
    reqparam->m_ushByteOffset = 0;
    reqparam->m_ushSize = MAX_BITMAP_SIZE_IN_BYTES;

    reqmsg.m_pMsgPara = reqparam;

    int ret = transfer.send_csmsg(cshead, reqmsg);

    if (ret)
    {
        printf("send failed ret:%d, err:%s\n", ret, transfer.get_errmsg());
        return -1;
    }

    CMsg rspmsg;
    ret = transfer.recv_csmsg(&cshead, &rspmsg);
    if (ret)
    {
        printf("recv failed ret:%d, err:%s\n", ret, transfer.get_errmsg());
        return -1;
    }

    CRspFetchBitmap *rspparam = (CRspFetchBitmap*)rspmsg.m_pMsgPara;
    printf("result:%d, rev:%ld\n", rspparam->m_iResult, rspparam->m_uiRev);
    for (unsigned short i = 0; i < rspparam->m_ushSize; ++i)
    {
        printf("%02x ", (unsigned char)rspparam->m_szMap[i]);
        if (7 == i % 8)
        {
            printf("\n");
        }
    }

    return 0;
}


int main(int argc, char** argv)
{
    if (argc < 2)
    {
        printf("usage: %s <uin>\n", argv[0]);
        return 0;
    }

    unsigned int uin = strtoul(argv[1], NULL, 10);
    CMsg::RegisterProtocolCreator(my_create_para);
    csmsg_transfer trans;
    trans.initialize();
    trans.add_service("192.168.1.110", 443);
    int ret = trans.prepare_transfer();
    if (ret)
    {
        printf("preparation failed:%d\n", ret);
        return -1;
    }

//     ret = update_bitmap(uin, trans);
//     if (ret)
//     {
//         printf("update failed\n");
//         return 0;
//     }

    ret = fetch_bitmap(uin, trans);
    if (ret)
    {
        printf("fetch failed\n");
        return 0;
    }

    return 0;
}
